﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading;
using System.Windows;
using Ninject;
using SydEnergiPrototype.Logic;
using SydEnergiPrototype.Model;
using SydEnergiPrototype.DataRepositoryServiceRef;

namespace SydEnergiPrototype.DataAccess
{
    public class DataRepository : IDataRepository
    {
        private IDataRepositoryService _client;
        private ObservableCollection<CabinetDto> cabinetDtos;

        public void GetCabinetsAsync(ReturnResult callback)
        {
            _client.BeginGetCabinets(GetCabinetsCompleted, callback);
        }

        public void SetCabinetsAsync(Action callback, Cabinets cabinets)
        {
            var cabinetDtos = new ObservableCollection<CabinetDto>();
            var parser = _parserFactory.Make(typeof (Cabinet));
            foreach (var cabinet in cabinets)
            {
                cabinetDtos.Add(parser.ParseToDto<ICabinet, CabinetDto>(cabinet));
            }
            _client.BeginSetCabinets(cabinetDtos, SetCabinetsCompleted, callback);
        }

        private void SetCabinetsCompleted(IAsyncResult result)
        {
            _client.EndSetCabinets(result);
            var callback = result.AsyncState as Action;
            if (callback != null)
                callback();
        }

        private void GetCabinetsCompleted(IAsyncResult result)
        {
            cabinetDtos = _client.EndGetCabinets(result);
            var cabinets = new Cabinets();
            var parser = _parserFactory.Make(typeof (CabinetDto));
            Deployment.Current.Dispatcher.BeginInvoke(() =>
            {
                foreach (var cabinetDto in cabinetDtos)
                {
                    cabinets.Add(parser.ParseFromDto<CabinetDto, Cabinet>(cabinetDto));
                }
                ((ReturnResult)result.AsyncState).Notify(cabinets);
            });
        }

        private readonly IParserFactory _parserFactory;
        private readonly IFactory _factory;

        [Inject]
        public DataRepository(IParserFactory parserFactory, IFactory factory)
        {
            if (parserFactory == null)
                throw new ArgumentNullException("parserFactory");
            _parserFactory = parserFactory;

            if(factory == null)
                throw new ArgumentNullException();
            _factory = factory;

            _client = _factory.CreateDataRepositoryClient();
        }
    }
}
